// CodeConverter.v - Code Converter
//
// Input(s):
// ---------
// 'clk'      - 100 MHz system clock
// 'reset'    - Reset pin
// 'pbtn_dn'  - debounced output of the push buttons
//
// Output(s):
// ----------
// 'compCounter'  - compass heading
// 'motion'       - motion indicator input
//
// Descrip tion:
// ------------
// Code Converter is a module that takes debounced inputs from the pushbuttons
// on the nexys 3 board. It sends the push button inputs to a ButtonPressDecoder 
// module. The output of the ButtonPressDecoder are as follows:
//          * .decode: 3-bit decoded output
//            movFWD    : 3'd1; 
//            movREV    : 3'd2; 
//            rotCW_2x  : 3'd3;  
//            rotCCW_2x : 3'd4;
//            rotCW_1x  : 3'd5;
//            rotCCW_1x : 3'd6;
//            stopMotor : 3'b111
//
// The module samples the decoded output from the ButtonPressDecoder module @
// 100 Hz rate. If a rotation is performed in during the sampling period, an 
// up-down counter is incremented or decremented depending on the direction of 
// the rotation. If the rotation is happening at speed 2x, the increments are 
// doubled. 
//
// Copyright Jabeer Ahmed and Caleb Mathisen, 2014
// 
// Created By:      Jabeer Ahmed
// Author(s) :      Jabeer Ahmed, Caleb Mathisen
// Last Modified:   TODO
//
// Revision History:
// -----------------
//
////////////////////////////////////////////////////////////////////////////////

`timescale  1 ns / 1 ns
module CodeConverter (
  //inputs
  input               clk,                      // clock 100 MHz    
  input               reset,                    // reset
  input       [3:0]   pbtn_db,                  // pushbutton debounced inputs

  //outputs
  output reg  [8:0]   compCounter    = 9'b0		  // compass up-down counter 
);

  wire        [2:0]   dcode_out;  					    // decoded output  
  reg         [19:0]  counter        = 32'h0;   // counts 1,000,000 cycles
  reg                 sample         = 1'b0;    // flag to trigger sample

  wire            slow_clk;
  reg    [31:0]   slow_clk_ivl  = 31'd1_000_000;          // half clock
   	
  // Button Press Decoder output
  localparam movFWD       = 3'd1; 
  localparam movREV       = 3'd2; 
  localparam rotCW_2x     = 3'd3;  
  localparam rotCCW_2x    = 3'd4;
  localparam rotCW_1x     = 3'd5;
  localparam rotCCW_1x    = 3'd6;
  localparam stopMotor    = 3'b111;
  
  // switch between sim and hw interval mode
  localparam simulate     = 0;                    
  localparam interval_cnt = simulate ? 22'd10 : 22'd1_000_000;

  // Button Press Decoder instantiation
  ButtonPressDecoder btn_decoder(
    .clk(clk),                                  // connect input clk 100 MHz
    .pbtn_db(pbtn_db),                          // connect push buttons
    .decode(dcode_out)                          // connect decoded output
  );                                                
	
  ClockDivider clk_div(clk, slow_clk_ivl, reset, slow_clk);
  
  always @ (slow_clk) 
		sample <= slow_clk;
		
  // When the sample flag is set 
  always @(posedge sample or posedge reset) begin      
  	if (reset) begin
  	 compCounter = 9'b0;
	 end
  	else begin    
      case (dcode_out)
        rotCW_1x  : begin
              if (compCounter == 9'd359)
                  compCounter = 9'd0;
              else
                  compCounter = compCounter + 9'd1;
          end
        rotCCW_1x : begin
              if (compCounter == 9'd0)
                  compCounter = 9'd359;
              else
                  compCounter = compCounter - 9'd1;
          end
        
//        rotCW_2x  : compCounter = compCounter + 2'd2;
//        rotCCW_2x : compCounter = compCounter - 2'd2;
      endcase
      // if the compass counter goes negative wrap around to make it 0-359 deg                                      
      if (compCounter < 0) begin
        compCounter = 9'd360 - compCounter;
      end
    end      
  end

endmodule